package com.java.common.config;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import org.apache.commons.configuration.CombinedConfiguration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.DefaultConfigurationBuilder;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.lang.StringUtils;

import com.java.common.base.model.LabelValue;

/**
 * 读写配置文件
 * 
 * @author lhl
 */
public class ConfigurationManager {    
    private static DefaultConfigurationBuilder factory;
    private static CombinedConfiguration configuration;
    
    
    static {
        factory = new DefaultConfigurationBuilder(Constants.CONFIG_FILE);
        try {
            configuration = factory.getConfiguration(true);
        }catch(ConfigurationException cfge) {
            throw new RuntimeException(cfge);
        }
    }
    
    public static CombinedConfiguration getConfiguration() {
//        try {
//            return factory.getConfiguration();
//        }catch(ConfigurationException cfge) {
//            throw new SystemException(cfge);
//        }
            return configuration;
    }
    

    
    /**
     * 从配置文件读取代码表,要求在配置文件中以codes开始
     * @param codeName
     * @return
     */
    public static List<LabelValue> getCodeTable(String codeName) {
        List<LabelValue> codes = new ArrayList<LabelValue>();
        String codeFullName = "codes." + codeName + ".entry";

        List<?> xmlCodes = ((CombinedConfiguration) getConfiguration()).configurationsAt(codeFullName);
        for(Iterator<?> it = xmlCodes.iterator(); it.hasNext();) {
            HierarchicalConfiguration sub = (HierarchicalConfiguration) it.next();
            String key = sub.getString("key");
            String value = sub.getString("value");
            codes.add(new LabelValue(value, key));
        }
       
        return codes;
    }
    
    /**
     * 从配置文件读取代码表,并返回到一个Map中
     * 要求在配置文件中以codes开始
     * @param codeName
     * @return
     */
    public static HashMap<String,String> getCodeTableMap(String codeName) {
    	HashMap<String,String> map = new HashMap<String,String>();
        String codeFullName = "codes." + codeName + ".entry";
        
        List<?> xmlCodes = ((CombinedConfiguration) getConfiguration()).configurationsAt(codeFullName);
        for(Iterator<?> it = xmlCodes.iterator(); it.hasNext();) {
            HierarchicalConfiguration sub = (HierarchicalConfiguration) it.next();
            String key = sub.getString("key");
            String value = sub.getString("value");
            map.put(key, value);
        }
       
        return map;
    }
    
    
    public static List<LabelValue> getAppConfigValue(String appConfigValue){
    	List<LabelValue> codes = new ArrayList<LabelValue>();
        String codeFullName = appConfigValue + ".entry";
        
        List<?> xmlCodes = ((CombinedConfiguration) getConfiguration()).configurationsAt(codeFullName);
        for(Iterator<?> it = xmlCodes.iterator(); it.hasNext();) {
            HierarchicalConfiguration sub = (HierarchicalConfiguration) it.next();
            String key = sub.getString("key");
            String value = sub.getString("value");
            codes.add(new LabelValue(value, key));
        }
       
        return codes;
    }
    
    /** 得到code-table.xml中的单一值List  
     * 如:
     * <seal><seal-controled-class><value>A</value><value>B</value></seal-controled-class></seal>
     * appConfigValue="seal.seal-controled-class"  返回List包含A,B
     */
    public static List<String> getAppConfigSingleValues(String appConfigValue){
    	List<String> values = new ArrayList<String>();
        
        List<?> xmlCodes = ((CombinedConfiguration) getConfiguration()).configurationsAt("codes."+appConfigValue);
        for(Iterator<?> it = xmlCodes.iterator(); it.hasNext();) {
            HierarchicalConfiguration sub = (HierarchicalConfiguration) it.next();
            values.add(sub.getString("value"));
        }
       
        return values;
    }

    
    /**
     * 得到某路径节点下的属性值，匹配第一个找到的内容
     * @param nodePath
     * @param propertyName
     * @param defaultValue
     * @return String
     */
    public static String getNodeAttribute(
    		String nodePath, 
    		String propertyName, 
    		String defaultValue)
    {
    	List<?> xmlNodes = ((CombinedConfiguration) getConfiguration()).configurationsAt(nodePath);
    	if(xmlNodes.size() > 0){
    		for(Iterator<?> it = xmlNodes.iterator(); it.hasNext();) {
                HierarchicalConfiguration sub = (HierarchicalConfiguration) it.next();
                String value = sub.getString("[@"+propertyName+"]");
                if(!StringUtils.isBlank(value)){
                	return value;
                }
            }
    	}

    	return defaultValue;
    }

    public static String getCodeValue(String codeName, String key) {
        List<LabelValue> codes = getCodeTable(codeName);

        for(int i = 0; i < codes.size(); i++) {
            LabelValue code = (LabelValue) codes.get(i);
            if(code.getValue().equals(key)) {
                return code.getLabel();
            }
        }
        return null;
    }
    
    public static List<String> getCodekeysByValue(String codeName,String value){
    	 List<LabelValue> codes = getCodeTable(codeName);
    	 List<String> result = new ArrayList<String>();
    	 
    	 for(int i = 0; i < codes.size(); i++) {
             LabelValue code = (LabelValue) codes.get(i);
             if(code.getLabel().equals(value)) {
                 result.add(code.getValue());
             }
         }
    	
    	 return result;
    }
    
    
	public static String getAppConfigValue(String appConfigName, String key){
    	List<LabelValue> codes = getAppConfigValue(appConfigName);
    	
    	for(int i = 0; i < codes.size(); i++) {
            LabelValue code = (LabelValue) codes.get(i);
            if(code.getValue().equals(key)) {
                return code.getLabel();
            }
        }
        return null;
    }

    public static List<?> getHelpConfig() {
        return ((CombinedConfiguration) getConfiguration()).configurationsAt("cshitem");
    }
    public static String getHelpTargetByURL(String url) {
        List<?> items = ((CombinedConfiguration) getConfiguration()).configurationsAt("cshitem.cshitem");

        for(Iterator<?> it = items.iterator(); it.hasNext();) {
            HierarchicalConfiguration sub = (HierarchicalConfiguration) it.next();
            if(url.equals(sub.getString("[@context]")))
                return sub.getString("[@target]");
        }
        return null;
    }
    
//    public static Configuration subset(String prefix) {
//        return getConfiguration().subset(prefix);
//    }
    
    public static boolean isEmpty() {
        return getConfiguration().isEmpty();
    }
    
    public static boolean containsKey(String key) {
        return getConfiguration().containsKey(key);
    }
    
    public static void addProperty(String key, Object value) { 
        getConfiguration().addProperty(key, value);
    }
    
    public static void setProperty(String key, Object value) {
        getConfiguration().setProperty(key, value);
    }
    
    public static void clearProperty(String key) {
        getConfiguration().clearProperty(key);
    }
    
    public static void clear() {
        getConfiguration().clear();
    }
    
    public static Object getProperty(String key) {
        return getConfiguration().getProperty(key);
    }
    
    public static Iterator<?> getKeys(String prefix) {
        return getConfiguration().getKeys(prefix);
    }
    
    public static Iterator<?> getKeys() {
        return getConfiguration().getKeys();
    }
    
    public static Properties getProperties(String key) {
        return getConfiguration().getProperties(key);
    }
    
    public static boolean getBoolean(String key) {
        return getConfiguration().getBoolean(key);
    }
    
    public static boolean getBoolean(String key, boolean defaultValue) {
        return getConfiguration().getBoolean(key, defaultValue);
    }
    
    public static Boolean getBoolean(String key, Boolean defaultValue) {
        return getConfiguration().getBoolean(key, defaultValue);
    }
    
    public static byte getByte(String key) {
        return getConfiguration().getByte(key);
    }
    
    public static byte getByte(String key, byte defaultValue) {
        return getConfiguration().getByte(key, defaultValue);
    }
    
    public static Byte getByte(String key, Byte defaultValue) {
        return getConfiguration().getByte(key, defaultValue);
    }
    
    public static double getDouble(String key) {
        return getConfiguration().getDouble(key);
    }
    
    public static double getDouble(String key, double defaultValue) {
        return getConfiguration().getDouble(key, defaultValue);
    }
    
    public static Double getDouble(String key, Double defaultValue) {
        return getConfiguration().getDouble(key, defaultValue);
    }
    
    public static float getFloat(String key) {
        return getConfiguration().getFloat(key);
    }
    
    public static float getFloat(String key, float defaultValue) {
        return getConfiguration().getFloat(key, defaultValue);
    }
    
    public static Float getFloat(String key, Float defaultValue) {
        return getConfiguration().getFloat(key,defaultValue);
    }
    
    public static int getInt(String key) {
        return getConfiguration().getInt(key);
    }
    
    public static int getInt(String key, int defaultValue) {
        return getConfiguration().getInt(key, defaultValue);
    }
    
    public static Integer getInteger(String key, Integer defaultValue) {
        return getConfiguration().getInteger(key, defaultValue);
    }
    
    public static long getLong(String key) {
        return getConfiguration().getLong(key);
    }
    
    public static long getLong(String key, long defaultValue) {
        return getConfiguration().getLong(key, defaultValue);
    }
    
    public static Long getLong(String key, Long defaultValue) {
        return getConfiguration().getLong(key, defaultValue);
    }
    
    public static short getShort(String key) {
        return getConfiguration().getShort(key);
    }
    
    public static short getShort(String key, short defaultValue) {
        return getConfiguration().getShort(key, defaultValue);
    }
    
    public static Short getShort(String key, Short defaultValue) {
        return getConfiguration().getShort(key, defaultValue);
    }
    
    public static BigDecimal getBigDecimal(String key) {
        return getConfiguration().getBigDecimal(key);
    }
    
    public static BigDecimal getBigDecimal(String key, BigDecimal defaultValue) {
        return getConfiguration().getBigDecimal(key, defaultValue);
    }
    
    public static BigInteger getBigInteger(String key) {
        return getConfiguration().getBigInteger(key);
    }
    
    public static BigInteger getBigInteger(String key, BigInteger defaultValue) {
        return getConfiguration().getBigInteger(key, defaultValue);
    }
    
    /**
     * 取得单一值
     * @param key
     * @return
     */
    public static String getString(String key) {
        return getConfiguration().getString(key);
    }
    /**
     * 取得单一值
     * @param key
     * @param defaultValue
     * @return
     */
    public static String getString(String key, String defaultValue) {
        return getConfiguration().getString(key, defaultValue);
    }
    
    public static String[] getStringArray(String key) {
        return getConfiguration().getStringArray(key);
    }
    
    public static List<?> getList(String key) {
        return getConfiguration().getList(key);
    }
    
    public static List<?> getList(String key, List<?> defaultValue) {
        return getConfiguration().getList(key, defaultValue);
    }  
    public static void main(String[] args) {
    	System.out.println(ConfigurationManager.getString("rowCount"));
	}
}
